package com.johnny.xia.util.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.core.Validator;

public class HttpSSLUtil{
    
   static final Logger LOGGER = LoggerFactory.getLogger(HttpSSLUtil.class);

    
    public static void httpsPost(String urlString,Map<String,String> heard,String dataJson) {
        HttpsURLConnection.setDefaultHostnameVerifier(new HttpSSLUtil().new NullHostNameVerifier());
        HttpURLConnection httpConn;
        OutputStream out = null;
        try{
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            
            URL url = new URL(urlString);
            httpConn = (HttpURLConnection) url.openConnection();
            
            if(heard != null && !heard.isEmpty()) {
                for(Map.Entry<String, String> entry : heard.entrySet()) {
                    httpConn.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
            httpConn.setRequestMethod("POST");
           
            httpConn.setDoOutput(true);
            httpConn.setDoInput(true);
            out = httpConn.getOutputStream();
            out.write(dataJson.getBytes());
            
            byte[] datas = readInputStream(httpConn.getInputStream());
            String result=new String(datas);
            LOGGER.info(result);
        }catch (Exception e){
            LOGGER.error("httpclient error!",e);
        }finally {
            try{
                if(Validator.isNotNullOrEmpty(out)){
                    out.close();
                }
            }catch (IOException e){
                LOGGER.error("io close error!",e);
            }
        }
    }
    
    /**
     * 从输入流中读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        try{
            while( (len = inStream.read(buffer)) !=-1 ){
                outStream.write(buffer, 0, len);
            }
            byte[] data = outStream.toByteArray();
            return data;
        }catch (IOException e){
            LOGGER.error("io write error!",e);
        }finally {
            try{
                outStream.close();
                inStream.close();
            }catch (IOException e){
                LOGGER.error("io close error!",e);
            }
        }
        return null;
    }
    
    /**
     * 接口为HTTPS协议时，有可能出现认证失败的情况，这里修改一下，可以直接绕过认证
     * @author johnny xia
     */
    static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
            
        }

        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
            
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
       
    } };
    
    /**
     * 接口为HTTPS协议时，有可能出现认证失败的情况，这里修改一下，可以直接绕过认证
     * @author johnny xia
     */
    public class NullHostNameVerifier implements HostnameVerifier {
        /*
         * (non-Javadoc)
         * 
         * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String,
         * javax.net.ssl.SSLSession)
         */
        public boolean verify(String arg0, SSLSession arg1) {
            return true;
        }
    }
    
    public static void main(String[] args){
        Map<String,String> heard = new HashMap<String, String>();
        heard.put("Authorization", "ZmFjYjJiMGMtNGI0Yy00M2I3LTg3YjItZWQzM2EzY2JlNmJk");
        heard.put("Content-Type", "application/json");
        
        String urlString = "https://heroku.esprit.com.hk/customer";
        httpsPost(urlString, heard, "");
    }
}
